package com.lkdont.android.media.opengl

import android.opengl.EGL14
import android.opengl.EGLContext
import android.opengl.EGLSurface
import android.view.Surface
import com.lkdont.android.media.MediaException

/**
 * 输入数据Surface
 */
class DataInputSurface(surface: Surface) {

    private var eglSurface: EGLSurface = EGL14.EGL_NO_SURFACE
    private var eglCore: EGLCore? = null
    private var surface: Surface?
    private var frameProgram: FrameProgram? = null

    init {
        this.surface = surface
    }

    /*** 设置OpenGL上下文 */
    fun setEGLContext(eglContext: EGLContext) {
        if (surface == null) {
            throw MediaException("setEGLContext fail, the surface was released.")
        }
        releaseEglSurface()
        frameProgram?.release()
        eglCore?.release()
        eglCore = EGLCore(eglContext, EGLCore.FLAG_RECORDABLE)
        createEglSurface(surface!!)
        makeCurrent()
        // 创建绘制帧程序
        frameProgram = FrameProgram()
        frameProgram!!.textureId = textureId
    }

    private fun createEglSurface(surface: Any) {
        if (eglSurface != EGL14.EGL_NO_SURFACE) {
            throw MediaException("EGLSurface already created.")
        }
        if (eglCore == null) {
            throw MediaException("EGLCore is null, make sure EGLContext was set.")
        }
        eglSurface = eglCore!!.createWindowSurface(surface)
    }

    private fun releaseEglSurface() {
        if (eglSurface == EGL14.EGL_NO_SURFACE) {
            return
        }
        if (eglCore == null) {
            throw MediaException("EGLCore is null, make sure EGLContext was set.")
        }
        eglCore!!.releaseSurface(eglSurface)
        eglSurface = EGL14.EGL_NO_SURFACE
    }

    private fun makeCurrent() {
        if (eglSurface == EGL14.EGL_NO_SURFACE) {
            throw MediaException("EGLSurface is not created.")
        }
        if (eglCore == null) {
            throw MediaException("EGLCore is null, make sure EGLContext was set.")
        }
        eglCore!!.makeCurrent(eglSurface)
    }

    private fun swapBuffers() {
        if (eglSurface == EGL14.EGL_NO_SURFACE) {
            throw MediaException("EGLSurface is not created.")
        }
        if (eglCore == null) {
            throw MediaException("EGLCore is null, make sure EGLContext was set.")
        }
        eglCore!!.swapBuffers(eglSurface)
    }

    private fun setPresentationTime(nanoSec: Long) {
        if (eglSurface == EGL14.EGL_NO_SURFACE) {
            throw MediaException("EGLSurface is not created.")
        }
        if (eglCore == null) {
            throw MediaException("EGLCore is null, make sure EGLContext was set.")
        }
        eglCore!!.setPresentationTime(eglSurface, nanoSec)
    }

    fun release() {
        releaseEglSurface()
        surface?.release()
        surface = null
        frameProgram?.release()
        frameProgram = null
        eglCore?.release()
        eglCore = null
    }

    var textureId: Int = 0
        set(value) {
            field = value
            frameProgram?.textureId = value
        }

    fun draw(timestamp: Long, texMatrix: FloatArray) {
        if (eglSurface == EGL14.EGL_NO_SURFACE) {
            // 还没有初始化
            return
        }
        // 首先把画面“画”在Surface上
        frameProgram!!.texMatrix = texMatrix
        frameProgram!!.draw()
        // 设置画面显示时间
        setPresentationTime(timestamp)
        // 切换缓冲，并自动将数据输出给编码器
        swapBuffers()
    }
}